import * as Types from 'containers/ActionTypes';
import * as Helper from 'Helper';
import * as AuthService from 'services/MyAuthService';
import * as Definitions from 'containers/Definitions';
import * as Cookies from 'js-cookie';

/*
 * action creators
 */
const loginRequest = () => ({
  type: Types.MY.SESSION.LOGIN_REQUEST,
});

const loginSuccess = user => ({
  type: Types.MY.SESSION.LOGIN_SUCCESS,
  user,
});

const logoutRequest = () => ({
  type: Types.MY.SESSION.LOGOUT_REQUEST,
});

const logoutSuccess = () => ({
  type: Types.MY.SESSION.LOGOUT_SUCCESS,
});

const tokenRequest = () => ({
  type: Types.MY.SESSION.TOKEN_REQUEST,
});

const tokenSuccess = (token, expires_in) => ({
  type: Types.MY.SESSION.TOKEN_SUCCESS,
  token,
  expires_in,
});

// open new url in current window
const openUrlInCurrent = function (url) {
  window.location.href = url;
};

const REDIRECT_URI = encodeURIComponent(
  `${window.location.protocol}//${window.location.host}/login`,
);

export const login = () => (dispatch) => {
  const clientId = APP_CONFIG.clientId;

  // one of ['zh', 'en']
  const lang = 'zh';

  dispatch(loginRequest());

  openUrlInCurrent(`${APP_CONFIG.oauthEndPoint}/api/oauth/authorize?client_id=${clientId}&state=hypereal&response_type=code&redirect_uri=${REDIRECT_URI}&lang=${lang}`);
};

export const loginFromCookies = () => (dispatch) => {
  const token = Cookies.get(Definitions.ACCESS_TOKEN_KEY);
  if (token) {
    dispatch(tokenSuccess(token));
    return AuthService.me(token)
      .then((res) => {
        dispatch(loginSuccess(res));
        return res;
      });
  }
};

export const fetchToken = data => (dispatch) => {
  dispatch(tokenRequest());

  const bodyData = Object.assign({}, {
    client_id: APP_CONFIG.clientId,
    client_secret: APP_CONFIG.secret,
    grant_type: 'authorization_code',
    redirect_uri: REDIRECT_URI,
  }, data);

  return AuthService.fetchToken(require('query-string').stringify(bodyData))
    .then(([token, expires_in]) => {
      const expires_in_days = expires_in / (3600 * 24);
      Cookies.remove(Definitions.ACCESS_TOKEN_KEY, { domain: Definitions.TOKEN_DOMAIN, path: '/' });
      Cookies.set(Definitions.ACCESS_TOKEN_KEY, token, { expires: expires_in_days, domain: Definitions.TOKEN_DOMAIN, path: '/' });
      dispatch(tokenSuccess(token, expires_in));
      return token;
    });
};

export const me = token => dispatch => AuthService.me(token)
  .then((res) => {
    dispatch(loginSuccess(res));
    return res;
  });

export const signout = () => (dispatch, getState) => {
  dispatch(logoutRequest());
  const state = getState();
  const token = Helper.getMyToken(state);
  return AuthService.signout(token).then(() => {
    Cookies.remove(Definitions.ACCESS_TOKEN_KEY, { domain: Definitions.TOKEN_DOMAIN, path: '/' });
    dispatch(logoutSuccess());
  });
};
